📄 matrix.java
字号:
} else {
// Generate Householder vector.
for (int k = 0; k < i; k++) {
d[k] /= scale;
h += d[k] * d[k];
}
double f = d[i-1];
double g = Math.sqrt(h);
if (f > 0) {
g = -g;
}
e[i] = scale * g;
h = h - f * g;
d[i-1] = f - g;
for (int j = 0; j < i; j++) {
e[j] = 0.0;
}
// Apply similarity transformation to remaining columns.
for (int j = 0; j < i; j++) {
f = d[j];
V[j][i] = f;
g = e[j] + V[j][j] * f;
for (int k = j+1; k <= i-1; k++) {
g += V[k][j] * d[k];
e[k] += V[k][j] * f;
}
e[j] = g;
}
f = 0.0;
for (int j = 0; j < i; j++) {
e[j] /= h;
f += e[j] * d[j];
}
double hh = f / (h + h);
for (int j = 0; j < i; j++) {
e[j] -= hh * d[j];
}
for (int j = 0; j < i; j++) {
f = d[j];
g = e[j];
for (int k = j; k <= i-1; k++) {
V[k][j] -= (f * e[k] + g * d[k]);
}
d[j] = V[i-1][j];
V[i][j] = 0.0;
}
}
d[i] = h;
}
// v = new Matrix(V);
// System.out.println("before accumulate Matrix V \n" + v);
// Accumulate transformations.
for (int i = 0; i < n-1; i++) {
V[n-1][i] = V[i][i];
V[i][i] = 1.0;
double h = d[i+1];
if (h != 0.0) {
for (int k = 0; k <= i; k++) {
d[k] = V[k][i+1] / h;
}
for (int j = 0; j <= i; j++) {
double g = 0.0;
for (int k = 0; k <= i; k++) {
g += V[k][i+1] * V[k][j];
}
for (int k = 0; k <= i; k++) {
V[k][j] -= g * d[k];
}
}
}
for (int k = 0; k <= i; k++) {
V[k][i+1] = 0.0;
}
// v = new Matrix(V);
// System.out.println(" accumulate " + i + " Matrix V \n" + v);
}
for (int j = 0; j < n; j++) {
d[j] = V[n-1][j];
V[n-1][j] = 0.0;
}
V[n-1][n-1] = 1.0;
e[0] = 0.0;
// v = new Matrix(V);
// System.out.println(" end accumulate Matrix V \n" + v);
}
/**
* Symmetric tridiagonal QL algorithm.
*
* This function is adapted from the CERN Jet Java libraries, for it
* the following copyright applies (see also, text on top of file)
* Copyright (C) 1999 CERN - European Organization for Nuclear Research.
*
* @param V tridiagonalized matrix
* @param d
* @param e
* @param n size of matrix
* @Exception if factorization fails
*/
private void tql2 (double [][] V, double [] d, double [] e, int n)
throws Exception {
// This is derived from the Algol procedures tql2, by
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutine in EISPACK.
for (int i = 1; i < n; i++) {
e[i-1] = e[i];
}
e[n-1] = 0.0;
double f = 0.0;
double tst1 = 0.0;
double eps = Math.pow(2.0,-52.0);
for (int l = 0; l < n; l++) {
// Find small subdiagonal element
tst1 = Math.max(tst1,Math.abs(d[l]) + Math.abs(e[l]));
int m = l;
while (m < n) {
if (Math.abs(e[m]) <= eps*tst1) {
break;
}
m++;
}
// If m == l, d[l] is an eigenvalue,
// otherwise, iterate.
if (m > l) {
int iter = 0;
do {
iter = iter + 1; // (Could check iteration count here.)
// Compute implicit shift
double g = d[l];
double p = (d[l+1] - g) / (2.0 * e[l]);
double r = hypot(p,1.0);
if (p < 0) {
r = -r;
}
d[l] = e[l] / (p + r);
d[l+1] = e[l] * (p + r);
double dl1 = d[l+1];
double h = g - d[l];
for (int i = l+2; i < n; i++) {
d[i] -= h;
}
f = f + h;
// Implicit QL transformation.
p = d[m];
double c = 1.0;
double c2 = c;
double c3 = c;
double el1 = e[l+1];
double s = 0.0;
double s2 = 0.0;
for (int i = m-1; i >= l; i--) {
c3 = c2;
c2 = c;
s2 = s;
g = c * e[i];
h = c * p;
r = Matrix.hypot(p,e[i]);
e[i+1] = s * r;
s = e[i] / r;
c = p / r;
p = c * d[i] - s * g;
d[i+1] = h + s * (c * g + s * d[i]);
// Accumulate transformation.
for (int k = 0; k < n; k++) {
h = V[k][i+1];
V[k][i+1] = s * V[k][i] + c * h;
V[k][i] = c * V[k][i] - s * h;
}
// Matrix v = new Matrix(V);
// System.out.println("Matrix V \n" + v);
}
p = -s * s2 * c3 * el1 * e[l] / dl1;
e[l] = s * p;
d[l] = c * p;
// Check for convergence.
} while (Math.abs(e[l]) > eps*tst1);
}
d[l] = d[l] + f;
e[l] = 0.0;
}
// Sort eigenvalues and corresponding vectors.
/*
for (int i = 0; i < n-1; i++) {
int k = i;
double p = d[i];
for (int j = i+1; j < n; j++) {
if (d[j] < p) {
k = j;
p = d[j];
}
}
if (k != i) {
d[k] = d[i];
d[i] = p;
for (int j = 0; j < n; j++) {
p = V[j][i];
V[j][i] = V[j][k];
V[j][k] = p;
}
}
}*/
}
/**
* Returns sqrt(a^2 + b^2) without under/overflow.
*
* This function is adapted from the CERN Jet Java libraries, for it
* the following copyright applies (see also, text on top of file)
* Copyright (C) 1999 CERN - European Organization for Nuclear Research.
*
* @param a length of one side of rectangular triangle
* @param b length of other side of rectangular triangle
* @return lenght of third side
*/
protected static double hypot(double a, double b) {
double r;
if (Math.abs(a) > Math.abs(b)) {
r = b/a;
r = Math.abs(a)*Math.sqrt(1+r*r);
} else if (b != 0) {
r = a/b;
r = Math.abs(b)*Math.sqrt(1+r*r);
} else {
r = 0.0;
}
return r;
}
/**
* Test eigenvectors and eigenvalues.
* function is used for debugging
*
* @param V matrix with eigenvectors of A
* @param d array with eigenvalues of A
* @exception if new matrix cannot be made
*/
public boolean testEigen(Matrix V, double [] d, boolean verbose)
throws Exception {
boolean equal = true;
if (verbose) {
System.out.println("--- test Eigenvectors and Eigenvalues of Matrix A --------");
System.out.println("Matrix A \n" + this);
System.out.println("Matrix V, the columns are the Eigenvectors\n" + V);
System.out.println("the Eigenvalues are");
for (int k = 0; k < d.length; k++) {
System.out.println( Utils.doubleToString(d[k], 2));
}
System.out.println("\n---");
}
double [][] f = new double[V.numRows()][1];
Matrix F = new Matrix(f);
for (int i = 0; i < V.numRows(); i++) {
double [] col = V.getColumn(i);
double norm = 0.0;
for (int j = 0; j < col.length; j++) {
norm += Math.pow(col[j], 2.0);
}
norm = Math.pow(norm, 0.5);
F.setColumn(0, V.getColumn(i));
if (verbose)
System.out.println("Eigenvektor " + i + " =\n" + F + "\nNorm " + norm);
Matrix R = this.multiply(F);
if (verbose) {
System.out.println("this x Eigenvektor " + i + " =\n");
for (int k = 0; k < V.numRows(); k++) {
System.out.print(Utils.doubleToString(R.getElement(k, 0), 2) + " ");
}
System.out.println(" ");
System.out.println(" ");
System.out.println("Eigenvektor "+ i + " x Eigenvalue " +
Utils.doubleToString(d[i], 2) +" =");
}
for (int k = 0; k < V.numRows() && equal; k++) {
double dd = F.getElement(k, 0) * d[i];
double diff = dd - R.getElement(k, 0);
equal = Math.abs(diff) < Utils.SMALL;
if (Math.abs(diff) > Utils.SMALL)
System.out.println("OOOOOOps");
if (verbose) {
System.out.print( Utils.doubleToString(dd, 2) + " ");
}
}
if (verbose) {
System.out.println(" ");
System.out.println("---");
}
}
return equal;
}
/**
* Main method for testing this class.
*/
public static void main(String[] ops) {
double[] first = {2.3, 1.2, 5};
double[] second = {5.2, 1.4, 9};
double[] response = {4, 7, 8};
double[] weights = {1, 2, 3};
try {
// test eigenvaluedecomposition
double [][] m = {{1, 2, 3}, {2, 5, 6},{3, 6, 9}};
Matrix M = new Matrix(m);
int n = M.numRows();
double [][] V = new double[n][n];
double [] d = new double[n];
double [] e = new double[n];
M.eigenvalueDecomposition(V, d);
Matrix v = new Matrix(V);
// M.testEigen(v, d, );
// end of test-eigenvaluedecomposition
Matrix a = new Matrix(2, 3);
Matrix b = new Matrix(3, 2);
System.out.println("Number of columns for a: " + a.numColumns());
System.out.println("Number of rows for a: " + a.numRows());
a.setRow(0, first);
a.setRow(1, second);
b.setColumn(0, first);
b.setColumn(1, second);
System.out.println("a:\n " + a);
System.out.println("b:\n " + b);
System.out.println("a (0, 0): " + a.getElement(0, 0));
System.out.println("a transposed:\n " + a.transpose());
System.out.println("a * b:\n " + a.multiply(b));
Matrix r = new Matrix(3, 1);
r.setColumn(0, response);
System.out.println("r:\n " + r);
System.out.println("Coefficients of regression of b on r: ");
double[] coefficients = b.regression(r, 1.0e-8);
for (int i = 0; i < coefficients.length; i++) {
System.out.print(coefficients[i] + " ");
}
System.out.println();
System.out.println("Weights: ");
for (int i = 0; i < weights.length; i++) {
System.out.print(weights[i] + " ");
}
System.out.println();
System.out.println("Coefficients of weighted regression of b on r: ");
coefficients = b.regression(r, weights, 1.0e-8);
for (int i = 0; i < coefficients.length; i++) {
System.out.print(coefficients[i] + " ");
}
System.out.println();
a.setElement(0, 0, 6);
System.out.println("a with (0, 0) set to 6:\n " + a);
a.write(new java.io.FileWriter("main.matrix"));
System.out.println("wrote matrix to \"main.matrix\"\n" + a);
a = new Matrix(new java.io.FileReader("main.matrix"));
System.out.println("read matrix from \"main.matrix\"\n" + a);
} catch (Exception e) {
e.printStackTrace();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -