Added MatrixUtilsText (pulled some tests out of MathsUtilsTest which should have been here)

Added more tests for MI MultiVariate Gaussain
This commit is contained in:
joseph.lizier 2012-08-16 05:42:49 +00:00
parent b978034f18
commit af37fdf621
3 changed files with 220 additions and 105 deletions

View File

@ -6,6 +6,67 @@ import infodynamics.utils.RandomGenerator;
public class MutualInfoMultiVariateTester extends TestCase {
public void testCovarianceDoesntMatchDimensions(){
MutualInfoCalculatorMultiVariateGaussian miCalc =
new MutualInfoCalculatorMultiVariateGaussian();
miCalc.initialise(1, 1);
boolean caughtException = false;
// Check that we catch a covariance matrix which doesn't have
// the right number of rows
try {
miCalc.setCovariance(new double[][] {{2,1,0.5}, {1,2,0.5}, {0.5,0.5,2}});
} catch (Exception e) {
caughtException = true;
}
assertTrue(caughtException);
// Check that we catch a covariance matrix which isn't square
caughtException = false;
try {
miCalc.setCovariance(new double[][] {{2,1}, {1,2,0.5}});
} catch (Exception e) {
caughtException = true;
}
assertTrue(caughtException);
// Check that we catch a covariance matrix which isn't symmetric
caughtException = false;
try {
miCalc.setCovariance(new double[][] {{2,1}, {1.000001,2}});
} catch (Exception e) {
caughtException = true;
}
assertTrue(caughtException);
// Check that no exception is thrown for an ok covariance matrix
caughtException = false;
double[][] goodCovariance = new double[][] {{2,1}, {1,2}};
try {
miCalc.setCovariance(goodCovariance);
} catch (Exception e) {
caughtException = true;
}
assertFalse(caughtException);
// and that this covariance has been set:
assertEquals(goodCovariance, miCalc.covariance);
}
public void testAnalyticMatchesCouplingValue() throws Exception {
double[][] covarianceMatrix = {{1.0, 0}, {0, 1.0}};
MutualInfoCalculatorMultiVariateGaussian miCalc =
new MutualInfoCalculatorMultiVariateGaussian();
for (double covar = 0.0; covar < 1.0; covar += 0.01) {
// Insert the new covariance into the matrix:
covarianceMatrix[0][1] = covar;
covarianceMatrix[1][0] = covar;
miCalc.initialise(1, 1);
miCalc.setCovariance(covarianceMatrix);
assertEquals(-0.5 * Math.log(1.0 - covar*covar),
miCalc.computeAverageLocalOfObservations(), 0.00000000001);
}
}
public void testComputeSignificanceDoesntAlterAverage() throws Exception {
MutualInfoCalculatorMultiVariateGaussian miCalc =

View File

@ -135,95 +135,6 @@ public class MathsUtilsTest extends TestCase {
}
}
/**
* Test our Cholesky decomposition implementation
*
* @throws Exception
*/
public void testCholesky() throws Exception {
// Check some ordinary Cholesky decompositions:
double[][] A = {{6, 2, 3}, {2, 5, 1}, {3, 1, 4}};
// Expected result from Octave:
double[][] expectedL = {{2.44949, 0, 0}, {0.81650, 2.08167, 0},
{1.22474, 0, 1.58114}};
double[][] L = MatrixUtils.CholeskyDecomposition(A);
checkMatrix(expectedL, L, OCTAVE_RESOLUTION);
double[][] A2 = {{6, 2, 3, 1}, {2, 5, 1, 0.5}, {3, 1, 4, 2}, {1, 0.5, 2, 3}};
// Expected result from Octave:
double[][] expectedL2 = {{2.44949, 0, 0, 0}, {0.81650, 2.08167, 0, 0},
{1.22474, 0, 1.58114, 0}, {0.40825, 0.08006, 0.94868, 1.38814}};
double[][] L2 = MatrixUtils.CholeskyDecomposition(A2);
checkMatrix(expectedL2, L2, OCTAVE_RESOLUTION);
// Now check that it picks up asymmetric A:
double[][] asymmetricA = {{6, 2, 3}, {2, 5, 1}, {3, 1.0001, 4}};
boolean flaggedException = false;
try {
MatrixUtils.CholeskyDecomposition(asymmetricA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
// Now check that it picks up if A is not positive definite:
double[][] notpositiveDefiniteA = {{1, 2, 3}, {2, 4, 5}, {3, 5, 6}};
flaggedException = false;
try {
MatrixUtils.CholeskyDecomposition(notpositiveDefiniteA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
}
/**
* Test the inversion of symmetric positive definite matrices
*
* @throws Exception
*/
public void testInverseOfSymmPosDefMatrices() throws Exception {
// Check some ordinary matrices:
double[][] A = {{6, 2, 3}, {2, 5, 1}, {3, 1, 4}};
// Expected result from Octave:
double[][] expectedInv = {{0.29231, -0.07692, -0.2},
{-0.07692, 0.23077, 0}, {-0.2, 0, 0.4}};
double[][] inv = MatrixUtils.invertSymmPosDefMatrix(A);
checkMatrix(expectedInv, inv, OCTAVE_RESOLUTION);
double[][] A2 = {{6, 2, 3, 1}, {2, 5, 1, 0.5}, {3, 1, 4, 2}, {1, 0.5, 2, 3}};
// Expected result from Octave:
double[][] expectedInv2 = {{0.303393, -0.079840, -0.245509, 0.075848},
{-0.079840, 0.231537, 0.011976, -0.019960},
{-0.245509, 0.011976, 0.586826, -0.311377},
{0.075848, -0.019960, -0.311377, 0.518962}};
double[][] inv2 = MatrixUtils.invertSymmPosDefMatrix(A2);
checkMatrix(expectedInv2, inv2, OCTAVE_RESOLUTION);
// Now check that it picks up asymmetric A:
double[][] asymmetricA = {{6, 2, 3}, {2, 5, 1}, {3, 1.0001, 4}};
boolean flaggedException = false;
try {
MatrixUtils.invertSymmPosDefMatrix(asymmetricA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
// Now check that it picks up if A is not positive definite:
double[][] notpositiveDefiniteA = {{1, 2, 3}, {2, 4, 5}, {3, 5, 6}};
flaggedException = false;
try {
MatrixUtils.invertSymmPosDefMatrix(notpositiveDefiniteA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
}
public void testNormalPdf() throws Exception {
// Check values for x = -4:0.1:4 generated by octave
double[] expectedPdfMu0Std1 = {0.00013, 0.00020, 0.00029, 0.00042,
@ -430,20 +341,4 @@ public class MathsUtilsTest extends TestCase {
0.000001);
}
/**
* Check that all entries in the given matrix match those of the expected
* matrix
*
* @param expected
* @param actual
* @param resolution
*/
protected void checkMatrix(double[][] expected, double[][] actual, double resolution) {
for (int r = 0; r < expected.length; r++) {
for (int c = 0; c < expected[r].length; c++) {
assertEquals(expected[r][c], actual[r][c], resolution);
}
}
}
}

View File

@ -0,0 +1,159 @@
package infodynamics.utils;
import junit.framework.TestCase;
/**
* Test functionality of MatrixUtils methods.
*
* @author Joseph Lizier joseph.lizier_at_gmail.com
*
*/
public class MatrixUtilsTest extends TestCase {
private static double OCTAVE_RESOLUTION = 0.00001;
public void testIdentityMatrix() {
// Test identity matrix generation, including for size 0
for (int n = 0; n < 10; n++) {
double[][] I = MatrixUtils.identityMatrix(n);
assertNotNull(I);
assertEquals(n, I.length);
for (int i = 0; i < n; i++) {
assertEquals(n, I[i].length);
for (int j = 0; j < n; j++) {
assertEquals(i == j ? 1 : 0, I[i][j], 0.000000001);
}
}
}
}
/**
* Test our Cholesky decomposition implementation
*
* @throws Exception
*/
public void testCholesky() throws Exception {
// Check some ordinary Cholesky decompositions:
double[][] A = {{6, 2, 3}, {2, 5, 1}, {3, 1, 4}};
// Expected result from Octave:
double[][] expectedL = {{2.44949, 0, 0}, {0.81650, 2.08167, 0},
{1.22474, 0, 1.58114}};
double[][] L = MatrixUtils.CholeskyDecomposition(A);
checkMatrix(expectedL, L, OCTAVE_RESOLUTION);
double[][] A2 = {{6, 2, 3, 1}, {2, 5, 1, 0.5}, {3, 1, 4, 2}, {1, 0.5, 2, 3}};
// Expected result from Octave:
double[][] expectedL2 = {{2.44949, 0, 0, 0}, {0.81650, 2.08167, 0, 0},
{1.22474, 0, 1.58114, 0}, {0.40825, 0.08006, 0.94868, 1.38814}};
double[][] L2 = MatrixUtils.CholeskyDecomposition(A2);
checkMatrix(expectedL2, L2, OCTAVE_RESOLUTION);
// Now check that it picks up asymmetric A:
double[][] asymmetricA = {{6, 2, 3}, {2, 5, 1}, {3, 1.0001, 4}};
boolean flaggedException = false;
try {
MatrixUtils.CholeskyDecomposition(asymmetricA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
// Now check that it picks up if A is not positive definite:
double[][] notpositiveDefiniteA = {{1, 2, 3}, {2, 4, 5}, {3, 5, 6}};
flaggedException = false;
try {
MatrixUtils.CholeskyDecomposition(notpositiveDefiniteA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
}
/**
* Test the inversion of symmetric positive definite matrices
*
* @throws Exception
*/
public void testInverseOfSymmPosDefMatrices() throws Exception {
// Check some ordinary matrices:
double[][] A = {{6, 2, 3}, {2, 5, 1}, {3, 1, 4}};
// Expected result from Octave:
double[][] expectedInv = {{0.29231, -0.07692, -0.2},
{-0.07692, 0.23077, 0}, {-0.2, 0, 0.4}};
double[][] inv = MatrixUtils.invertSymmPosDefMatrix(A);
checkMatrix(expectedInv, inv, OCTAVE_RESOLUTION);
double[][] A2 = {{6, 2, 3, 1}, {2, 5, 1, 0.5}, {3, 1, 4, 2}, {1, 0.5, 2, 3}};
// Expected result from Octave:
double[][] expectedInv2 = {{0.303393, -0.079840, -0.245509, 0.075848},
{-0.079840, 0.231537, 0.011976, -0.019960},
{-0.245509, 0.011976, 0.586826, -0.311377},
{0.075848, -0.019960, -0.311377, 0.518962}};
double[][] inv2 = MatrixUtils.invertSymmPosDefMatrix(A2);
checkMatrix(expectedInv2, inv2, OCTAVE_RESOLUTION);
// Now check that it picks up asymmetric A:
double[][] asymmetricA = {{6, 2, 3}, {2, 5, 1}, {3, 1.0001, 4}};
boolean flaggedException = false;
try {
MatrixUtils.invertSymmPosDefMatrix(asymmetricA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
// Now check that it picks up if A is not positive definite:
double[][] notpositiveDefiniteA = {{1, 2, 3}, {2, 4, 5}, {3, 5, 6}};
flaggedException = false;
try {
MatrixUtils.invertSymmPosDefMatrix(notpositiveDefiniteA);
} catch (Exception e) {
flaggedException = true;
}
assertTrue(flaggedException);
}
/**
* Test the solving of matrix equations via Cholesky decomposition.
* Solving A*X = B
*
* @throws Exception
*/
public void testSolvingMatrixEquationsOfSymmPosDefMatrices() throws Exception {
// Check some ordinary matrices:
double[][] A = {{6, 2, 3}, {2, 5, 1}, {3, 1, 4}};
double[][] B = {{5}, {4}, {3}};
// Expected result from Octave:
double[][] expectedX = {{0.55385}, {0.53846}, {0.20000}};
double[][] X = MatrixUtils.solveViaCholeskyResult(
MatrixUtils.CholeskyDecomposition(A), B);
checkMatrix(expectedX, X, OCTAVE_RESOLUTION);
// Check more complicated example
double[][] A2 = {{6, 2, 3, 1}, {2, 5, 1, 0.5}, {3, 1, 4, 2}, {1, 0.5, 2, 3}};
double[][] B2 = {{10, 5, 4, 12}, {4, 6, -1, 4.3}, {20, 1, 0, -5}, {6, 3, 2, 1}};
// Check error conditions
}
/**
* Check that all entries in the given matrix match those of the expected
* matrix
*
* @param expected
* @param actual
* @param resolution
*/
protected void checkMatrix(double[][] expected, double[][] actual, double resolution) {
for (int r = 0; r < expected.length; r++) {
for (int c = 0; c < expected[r].length; c++) {
assertEquals(expected[r][c], actual[r][c], resolution);
}
}
}
}