package mikera.matrixx;
import static org.junit.Assert.*;
import org.junit.Test;
import mikera.indexz.Index;
import mikera.matrixx.algo.Inverse;
import mikera.matrixx.impl.AStridedMatrix;
import mikera.matrixx.impl.DiagonalMatrix;
import mikera.matrixx.impl.PermutationMatrix;
import mikera.matrixx.impl.RowMatrix;
import mikera.matrixx.impl.StridedMatrix;
import mikera.matrixx.impl.SubsetMatrix;
import mikera.matrixx.impl.VectorMatrixMN;
import mikera.matrixx.impl.ZeroMatrix;
import mikera.transformz.ATransform;
import mikera.transformz.MatrixTransform;
import mikera.vectorz.AVector;
import mikera.vectorz.Vector;
import mikera.vectorz.Vector3;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.SparseIndexedVector;
public class TestMisc {
@Test
public void testCompose() {
double angle = Math.random();
AVector v = Vectorz.createUniformRandomVector(3);
Matrix33 rot = Matrixx.createRotationMatrix(v, angle);
AMatrix tr = Matrixx.createRandomMatrix(6, 3);
AMatrix r = tr.compose(rot);
assertEquals(6, r.rowCount());
assertEquals(3, r.columnCount());
AVector x = Vectorz.createUniformRandomVector(3);
AVector x2 = x.clone();
AVector y = r.transform(x);
AVector y2 = tr.transform(rot.transform(x2));
assertTrue(y.epsilonEquals(y2));
}
@Test
public void test180RotationMatrix() {
AVector v = Vector.of(Math.random(), 0, 0);
double angle = Math.PI;
Matrix33 rot = Matrixx.createYAxisRotationMatrix(angle);
AVector r = rot.transform(v);
v.negate();
assertTrue(v.epsilonEquals(r));
}
@Test
public void testGeneralGenerator() {
for (int rows = 0; rows < 6; rows++) {
for (int columns = 0; columns < 6; columns++) {
AMatrix m = Matrixx.newMatrix(rows, columns);
assertTrue(m.isFullyMutable());
assertEquals(rows, m.rowCount());
assertEquals(columns, m.columnCount());
assertTrue(m.isZero());
}
}
}
@Test
public void testRandomRotation() {
AVector v = Vectorz.createUniformRandomVector(3);
AVector axis = Vectorz.createUniformRandomVector(3);
double angle = Math.random();
Matrix33 rot = Matrixx.createRotationMatrix(axis, angle);
AVector r = rot.transform(v);
assertEquals(v.magnitude(), r.magnitude(), 0.00001);
Matrix33 inv = rot.inverse();
AVector ri = inv.transform(r);
assertTrue(v.epsilonEquals(ri));
}
@Test
public void testScale() {
for (int i = 1; i < 10; i++) {
AVector v = Vectorz.newVector(i);
for (int j = 0; j < v.length(); j++) {
v.set(j, j + 1.3);
}
AVector tv = v.clone();
AMatrix m = Matrixx.createScaleMatrix(i, 2.3);
m.transform(v, tv);
assertEquals(v.magnitude() * 2.3, tv.magnitude(), 0.0001);
}
}
@Test
public void testBasicDeterminant() {
VectorMatrixMN mmn = new VectorMatrixMN(2, 2);
mmn.getRow(0).set(Vector.of(2, 1));
mmn.getRow(1).set(Vector.of(1, 2));
assertEquals(3.0, mmn.determinant(), 0.0);
}
@Test
public void testPermuteDeterminant() {
VectorMatrixMN mmn = new VectorMatrixMN(3, 3);
mmn.set(0, 1, 1);
mmn.set(1, 0, 1);
mmn.set(2, 2, 1);
assertEquals(-1.0, mmn.determinant(), 0.0);
}
@Test
public void testEquivalentDeterminant() {
Matrix33 m33 = new Matrix33();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
m33.set(i, j, Math.random());
}
VectorMatrixMN mmn = new VectorMatrixMN(3, 3);
mmn.set(m33);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
assertEquals(m33.get(i, j), mmn.get(i, j), 0.0);
}
assertEquals(m33.determinant(), mmn.determinant(), 0.00001);
}
@Test
public void testCompoundTransform() {
AVector v = Vector.of(1, 2, 3);
AMatrix m1 = Matrixx.createScaleMatrix(3, 2.0);
AMatrix m2 = Matrixx.createScaleMatrix(3, 1.5);
ATransform ct = new MatrixTransform(m2)
.compose(new MatrixTransform(m1));
assertTrue(Vector3.of(3, 6, 9).epsilonEquals(ct.transform(v)));
}
@Test
public void testRotationMatrix() {
AVector v=Vectorz.createUniformRandomVector(3);
double angle=Math.random();
Matrix33 rot=Matrixx.createRotationMatrix(v, angle);
AVector r=rot.transform(v);
assertEquals(v.get(0),r.get(0),0.00001);
assertEquals(v.get(1),r.get(1),0.00001);
assertEquals(v.get(2),r.get(2),0.00001);
assertEquals(v.magnitude(),r.magnitude(),0.00001);
assertTrue(r.epsilonEquals(v));
}
private void doInverseTest(AMatrix m) {
assert(m.rowCount()==m.columnCount());
AVector v = Vectorz.createUniformRandomVector(m.rowCount());
AMatrix mi=m.inverse();
assertEquals(1.0,m.determinant()*mi.determinant(),0.001);
assertTrue(mi.epsilonEquals(Inverse.calculate(m)));
AVector mv=m.transform(v);
AVector mimv=mi.transform(mv);
assertTrue(mimv.epsilonEquals(v));
// composition of matrix and its inverse should be an identity transform
MatrixTransform mt=new MatrixTransform(m);
ATransform id=mt.compose(new MatrixTransform(mi));
AVector idv=id.transform(v);
assertTrue(idv.epsilonEquals(v));
}
@Test
public void testInverse() {
doInverseTest(Matrixx.createRandomSquareMatrix(5));
doInverseTest(Matrixx.createRandomSquareMatrix(4));
doInverseTest(Matrixx.createRandomSquareMatrix(3));
doInverseTest(Matrixx.createRandomSquareMatrix(2));
doInverseTest(Matrixx.createRandomSquareMatrix(1));
}
@Test
public void testIdentity() {
for (int i=1; i<10; i++) {
AVector v=Vectorz.newVector(i);
for (int j=0; j<v.length(); j++) {
v.set(j,j+1.3);
}
AVector tv=v.clone();
AMatrix m=Matrixx.createImmutableIdentityMatrix(i);
m.transform(v, tv);
assertTrue(v.epsilonEquals(tv));
}
}
@Test
public void testFromDoubleArrays() {
double[][] dat=new double[][] {{1,2},{3,4}};
Matrix m=Matrixx.create(dat);
assertEquals(2,m.rowCount());
assertEquals(Vector.of(1,2,3,4),m.toVector());
}
@Test
public void testBasicCalculation() {
Matrix m = Matrix.create(2, 3);
m.set(0, 0, 1);
assertEquals(m.get(0, 0), 1, 0.0);
m.addAt(0, 2);
assertEquals(m.get(0, 0), 3, 0.0);
m.set(0, 1, 3);
assertEquals(m.get(0, 1), 3, 0.0);
m.subAt(1, 2);
assertEquals(m.get(0, 1), 1, 0.0);
m.set(1, 1, 4);
assertEquals(m.get(1, 1), 4, 0.0);
m.divideAt(4, 2);
assertEquals(m.get(1, 1), 2, 0.0);
m.set(1, 2, 5);
assertEquals(m.get(1, 2), 5, 0.0);
m.multiplyAt(5, 2);
assertEquals(m.get(1, 2), 10, 0.0);
}
@Test
public void testSubsetMatrix() {
SubsetMatrix m = SubsetMatrix.create(Index.of(0, 1, 2), 3);
assertEquals(1.0, m.get(0, 0), 0.0);
assertEquals(Vector.of(1, 0, 0), m.getRow(0));
assertEquals(Vector.of(0, 1, 0), m.getColumn(1));
assertEquals(Vector.of(0, 1, 0),
SparseIndexedVector.create(m.getColumn(1)));
}
@Test
public void testSubsetMatrix2() {
SubsetMatrix m = SubsetMatrix.create(Index.of(1, 1), 2);
assertEquals(Vector.of(0, 0), m.getColumn(0));
assertEquals(Vector.of(1, 1), m.getColumn(1));
}
@Test
public void testSubMatrix() {
Matrix m = (Matrix) Matrixx.newMatrix(4, 4);
Vectorz.fillIndexes(m.asVector());
// regression test
{
@SuppressWarnings("unused")
AStridedMatrix tsm = m.subMatrix(1, 1, 1, 1);
}
AStridedMatrix sm = m.subMatrix(1, 2, 1, 2);
assertEquals(2, sm.rowCount());
assertEquals(2, sm.columnCount());
assertTrue(sm.data == m.data);
assertEquals(
Matrixx.create(new double[][] { { 5.0, 6.0 }, { 9.0, 10.0 } }),
sm);
AStridedMatrix ssm = sm.subMatrix(1, 1, 1, 1);
assertEquals(Matrixx.create(new double[][] { { 10.0 } }), ssm);
}
@Test
public void testReordering() {
Matrix m = Matrix.create(new double[][] { { 1, 2 }, { 3, 4 } });
AMatrix m2 = m.clone();
m2 = m2.reorder(0, new int[] { 0, 1 });
assertEquals(m, m2);
m2 = m2.reorder(0, new int[] { 1, 0 });
assertEquals(Matrix.create(new double[][] { { 3, 4 }, { 1, 2 } }), m2);
}
@Test
public void testToString() {
assertEquals("[[0.0]]", ZeroMatrix.create(1, 1).toString());
}
@Test
public void testSymmetric() {
assertTrue(Matrixx.createIdentityMatrix(5).isSymmetric());
assertFalse(Matrixx.createRandomSquareMatrix(3).isSymmetric());
}
@Test
public void testRowMatrix() {
RowMatrix rm = RowMatrix.wrap(Vector.of(1, 2, 3));
assertEquals(rm.transposeInnerProduct(rm.toMatrix()), rm.getTranspose()
.innerProduct(rm));
}
@Test
public void testTriangular() {
AMatrix m1 = Matrixx.createRandomSquareMatrix(3);
assertTrue(!m1.isUpperTriangular());
assertTrue(!m1.isLowerTriangular());
AMatrix m2 = DiagonalMatrix.create(Vector.of(1, 2, 3));
assertTrue(m2.isUpperTriangular());
assertTrue(m2.isLowerTriangular());
AMatrix mut = Matrixx.create(Vector.of(1, 2), Vector.of(0, 4));
assertTrue(mut.isUpperTriangular());
assertTrue(!mut.isLowerTriangular());
AMatrix mlt = Matrixx.create(Vector.of(1, 0), Vector.of(3, 4));
assertTrue(!mlt.isUpperTriangular());
assertTrue(mlt.isLowerTriangular());
}
@Test
public void testDiagonalMatrix() {
DiagonalMatrix d = DiagonalMatrix.create(1, 2);
Matrix22 m = new Matrix22(1, 2, 3, 4);
assertEquals(new Matrix22(1, 2, 6, 8), d.compose(m));
assertEquals(new Matrix22(1, 4, 3, 8), m.compose(d));
}
@Test
public void testMatrixFromDoubles() {
Matrix m = Matrix.create(new double[][] { { 1, 0 }, { 0, 1 } });
assertTrue(m.isIdentity());
}
@Test
public void testJoin() {
DiagonalMatrix d1 = DiagonalMatrix.create(1, 2);
DiagonalMatrix d2 = DiagonalMatrix.create(3, 4);
assertEquals(Vector.of(0, 2, 0, 4), d1.join(d2, 1).slice(1));
}
@Test
public void testStridedMatrix() {
AMatrix om = Matrixx.createRandomMatrix(3, 4);
StridedMatrix sm = StridedMatrix.create(om);
AMatrix m = sm.getTranspose();
assertEquals(m.clone(), m);
assertEquals(m.getRow(1), m.clone().getRow(1));
assertEquals(m.getTranspose(), m.getTranspose().clone());
assertTrue(m.getTranspose() instanceof Matrix);
}
@Test
public void testPermutationMatrix() {
PermutationMatrix p = PermutationMatrix.createRandomPermutation(10);
assertTrue(p.innerProduct(p.getTranspose()).isIdentity());
try {
p = PermutationMatrix.create(0, 1, 2, 2, 4);
fail("Should not be able to create PermutationMatrix with invalid permutation");
} catch (Throwable t) {
// OK
}
}
}