package mikera.matrixx.solve.impl.lu;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.matrixx.impl.DiagonalMatrix;
import org.junit.Test;
public class TestLUSolver
{
protected double tol = 1e-8;
/**
* Checks to see if the modifyA() flag is set correctly
*/
@Test
public void modifiesA() {
Matrix A_orig = Matrix.createRandom(4,4);
Matrix A = A_orig.copy();
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A));
assertTrue(A_orig.epsilonEquals(A));
}
/**
* Checks to see if the modifyB() flag is set correctly
*/
@Test
public void modifiesB() {
Matrix A = Matrix.createRandom(4,4);
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A));
Matrix B = Matrix.createRandom(4,2);
Matrix B_orig = B.copy();
solver.solve(B);
assertTrue(B_orig.epsilonEquals(B));
}
/**
* See if a matrix that is more singular has a lower quality.
*/
@Test
public void checkQuality() {
Matrix A_good = DiagonalMatrix.create(4,3,2,1).toMatrix();
Matrix A_bad = DiagonalMatrix.create(4,3,2,0.1).toMatrix();
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A_good));
double q_good;
try {
q_good = solver.quality();
} catch( IllegalArgumentException e ) {
// quality is not supported
return;
}
solver = new LUSolver();
assertNotNull(solver.setA(A_bad));
double q_bad = solver.quality();
assertTrue(q_bad < q_good);
assertEquals(q_bad*10.0,q_good,1e-8);
}
/**
* See if quality is scale invariant
*/
@Test
public void checkQuality_scale() {
Matrix A = DiagonalMatrix.create(4,3,2,1).toMatrix();
Matrix Asmall = A.copy();
Asmall.scale(0.01);
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A));
double q;
try {
q = solver.quality();
} catch( IllegalArgumentException e ) {
// quality is not supported
return;
}
assertNotNull(solver.setA(Asmall));
double q_small = solver.quality();
assertEquals(q_small,q,1e-8);
}
/**
* A very easy matrix to decompose
*/
@Test
public void square_trivial() {
Matrix A = Matrix.create(new double[][] {{5, 2, 3}, {1.5, -2, 8}, {-3, 4.7, -0.5}});
Matrix b = Matrix.create(new double[][] {{18}, {21.5}, {4.9000}});
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A));
AMatrix x = solver.solve(b);
Matrix x_expected = Matrix.create(new double[][] {{1}, {2}, {3}});
assertTrue(x_expected.epsilonEquals(x,1e-8));
}
/**
* This test checks to see if it can solve a system that will require some algorithms to
* perform a pivot. Pivots can change the data structure and can cause solve to fail if not
* handled correctly.
*/
@Test
public void square_pivot() {
Matrix A = Matrix.create(new double[][] {{0, 1, 2}, {-2, 4, 9}, {0.5, 0, 5}});
Matrix b = Matrix.create(new double[][] {{8}, {33}, {15.5}});
LUSolver solver = new LUSolver();
assertNotNull(solver.setA(A));
Matrix x = solver.solve(b).toMatrix();
Matrix x_expected = Matrix.create(new double[][] {{1}, {2}, {3}});
assertTrue(x_expected.epsilonEquals(x,1e-6));
}
}