You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2008/11/27 16:50:42 UTC
svn commit: r721203 [2/2] - in /commons/proper/math/branches/MATH_2_0: ./
src/java/org/apache/commons/math/linear/ src/site/xdoc/
src/site/xdoc/userguide/ src/test/org/apache/commons/math/linear/
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/linear/EigenDecompositionImplTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/linear/EigenDecompositionImplTest.java?rev=721203&r1=721202&r2=721203&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/linear/EigenDecompositionImplTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/linear/EigenDecompositionImplTest.java Thu Nov 27 07:50:42 2008
@@ -17,6 +17,7 @@
package org.apache.commons.math.linear;
+import java.util.Arrays;
import java.util.Random;
import junit.framework.Test;
@@ -28,8 +29,6 @@
private double[] refValues;
private RealMatrix matrix;
- private static final double normTolerance = 1.e-10;
-
public EigenDecompositionImplTest(String name) {
super(name);
}
@@ -40,6 +39,69 @@
return suite;
}
+ public void testDimension1() {
+ RealMatrix matrix =
+ new RealMatrixImpl(new double[][] {
+ { 1.5 }
+ }, false);
+ EigenDecomposition ed = new EigenDecompositionImpl(matrix);
+ assertEquals(1.5, ed.getEigenvalue(0), 1.0e-15);
+ }
+
+ public void testDimension2() {
+ RealMatrix matrix =
+ new RealMatrixImpl(new double[][] {
+ { 59.0, 12.0 },
+ { Double.NaN, 66.0 }
+ }, false);
+ EigenDecomposition ed = new EigenDecompositionImpl(matrix);
+ assertEquals(75.0, ed.getEigenvalue(0), 1.0e-15);
+ assertEquals(50.0, ed.getEigenvalue(1), 1.0e-15);
+ }
+
+ public void testDimension3() {
+ RealMatrix matrix =
+ new RealMatrixImpl(new double[][] {
+ { 39632.0, -4824.0, -16560.0 },
+ { Double.NaN, 8693.0, 7920.0 },
+ { Double.NaN, Double.NaN, 17300.0 }
+ }, false);
+ EigenDecomposition ed = new EigenDecompositionImpl(matrix);
+ assertEquals(50000.0, ed.getEigenvalue(0), 3.0e-11);
+ assertEquals(12500.0, ed.getEigenvalue(1), 3.0e-11);
+ assertEquals( 3125.0, ed.getEigenvalue(2), 3.0e-11);
+ }
+
+ public void testDimension4WithSplit() {
+ RealMatrix matrix =
+ new RealMatrixImpl(new double[][] {
+ { 0.784, -0.288, 0.000, 0.000 },
+ { Double.NaN, 0.616, 0.000, 0.000 },
+ { Double.NaN, Double.NaN, 0.164, -0.048 },
+ { Double.NaN, Double.NaN, Double.NaN, 0.136 }
+ }, false);
+ EigenDecomposition ed = new EigenDecompositionImpl(matrix);
+ assertEquals(1.0, ed.getEigenvalue(0), 1.0e-15);
+ assertEquals(0.4, ed.getEigenvalue(1), 1.0e-15);
+ assertEquals(0.2, ed.getEigenvalue(2), 1.0e-15);
+ assertEquals(0.1, ed.getEigenvalue(3), 1.0e-15);
+ }
+
+ public void testDimension4WithoutSplit() {
+ RealMatrix matrix =
+ new RealMatrixImpl(new double[][] {
+ { 0.5608, -0.2016, 0.1152, -0.2976 },
+ { -0.2016, 0.4432, -0.2304, 0.1152 },
+ { 0.1152, -0.2304, 0.3088, -0.1344 },
+ { -0.2976, 0.1152, -0.1344, 0.3872 }
+ }, false);
+ EigenDecomposition ed = new EigenDecompositionImpl(matrix);
+ assertEquals(1.0, ed.getEigenvalue(0), 1.0e-15);
+ assertEquals(0.4, ed.getEigenvalue(1), 1.0e-15);
+ assertEquals(0.2, ed.getEigenvalue(2), 1.0e-15);
+ assertEquals(0.1, ed.getEigenvalue(3), 1.0e-15);
+ }
+
/** test dimensions */
public void testDimensions() {
final int m = matrix.getRowDimension();
@@ -58,7 +120,23 @@
double[] eigenValues = ed.getEigenvalues();
assertEquals(refValues.length, eigenValues.length);
for (int i = 0; i < refValues.length; ++i) {
- assertEquals(refValues[i], eigenValues[eigenValues.length - 1 - i], 3.0e-15);
+ assertEquals(refValues[i], eigenValues[i], 3.0e-15);
+ }
+ }
+
+ /** test eigenvalues for a big matrix. */
+ public void testBigMatrix() {
+ Random r = new Random(17748333525117l);
+ double[] bigValues = new double[200];
+ for (int i = 0; i < bigValues.length; ++i) {
+ bigValues[i] = 2 * r.nextDouble() - 1;
+ }
+ Arrays.sort(bigValues);
+ EigenDecomposition ed = new EigenDecompositionImpl(createTestMatrix(r, bigValues));
+ double[] eigenValues = ed.getEigenvalues();
+ assertEquals(bigValues.length, eigenValues.length);
+ for (int i = 0; i < bigValues.length; ++i) {
+ assertEquals(bigValues[bigValues.length - i - 1], eigenValues[i], 2.0e-14);
}
}
@@ -80,7 +158,7 @@
RealMatrix d = ed.getD();
RealMatrix vT = ed.getVT();
double norm = v.multiply(d).multiply(vT).subtract(matrix).getNorm();
- assertEquals(0, norm, normTolerance);
+ assertEquals(0, norm, 6.0e-13);
}
/** test that V is orthogonal */
@@ -88,7 +166,7 @@
RealMatrix v = new EigenDecompositionImpl(matrix).getV();
RealMatrix vTv = v.transpose().multiply(v);
RealMatrix id = MatrixUtils.createRealIdentityMatrix(vTv.getRowDimension());
- assertEquals(0, vTv.subtract(id).getNorm(), normTolerance);
+ assertEquals(0, vTv.subtract(id).getNorm(), 2.0e-13);
}
/** test solve dimension errors */
@@ -151,7 +229,7 @@
});
// using RealMatrix
- assertEquals(0, ed.solve(b).subtract(xRef).getNorm(), normTolerance);
+ assertEquals(0, ed.solve(b).subtract(xRef).getNorm(), 2.0e-12);
// using double[]
for (int i = 0; i < b.getColumnDimension(); ++i) {
@@ -191,26 +269,60 @@
}
private RealMatrix createTestMatrix(final Random r, final double[] eigenValues) {
- final RealMatrix v = createOrthogonalMatrix(r, eigenValues.length);
- final RealMatrix d = createDiagonalMatrix(eigenValues, eigenValues.length);
+ final int n = eigenValues.length;
+ final RealMatrix v = createOrthogonalMatrix(r, n);
+ final RealMatrix d = createDiagonalMatrix(eigenValues, n, n);
return v.multiply(d).multiply(v.transpose());
}
- private RealMatrix createOrthogonalMatrix(final Random r, final int size) {
+ public static RealMatrix createOrthogonalMatrix(final Random r, final int size) {
+
final double[][] data = new double[size][size];
+
for (int i = 0; i < size; ++i) {
- for (int j = 0; j < size; ++j) {
- data[i][j] = 2 * r.nextDouble() - 1;
- }
- }
- final RealMatrix m = new RealMatrixImpl(data, false);
- return new QRDecompositionImpl(m).getQ();
+ final double[] dataI = data[i];
+ double norm2 = 0;
+ do {
+
+ // generate randomly row I
+ for (int j = 0; j < size; ++j) {
+ dataI[j] = 2 * r.nextDouble() - 1;
+ }
+
+ // project the row in the subspace orthogonal to previous rows
+ for (int k = 0; k < i; ++k) {
+ final double[] dataK = data[k];
+ double dotProduct = 0;
+ for (int j = 0; j < size; ++j) {
+ dotProduct += dataI[j] * dataK[j];
+ }
+ for (int j = 0; j < size; ++j) {
+ dataI[j] -= dotProduct * dataK[j];
+ }
+ }
+
+ // normalize the row
+ norm2 = 0;
+ for (final double dataIJ : dataI) {
+ norm2 += dataIJ * dataIJ;
+ }
+ final double inv = 1.0 / Math.sqrt(norm2);
+ for (int j = 0; j < size; ++j) {
+ dataI[j] *= inv;
+ }
+
+ } while (norm2 * size < 0.01);
+ }
+
+ return new RealMatrixImpl(data, false);
+
}
- private RealMatrix createDiagonalMatrix(final double[] data, final int rows) {
- final double[][] dData = new double[rows][rows];
- for (int i = 0; i < data.length; ++i) {
- dData[i][i] = data[i];
+ public static RealMatrix createDiagonalMatrix(final double[] diagonal,
+ final int rows, final int columns) {
+ final double[][] dData = new double[rows][columns];
+ for (int i = 0; i < Math.min(rows, columns); ++i) {
+ dData[i][i] = diagonal[i];
}
return new RealMatrixImpl(dData, false);
}