package com.approximatrix.draco.math;

import static org.junit.Assert.*;

import java.util.Map;

import org.junit.Test;

public class MatrixSupportTest {

	private static final double[][] QRTestSource = {{0.0,1.0,1.0},{1.0,1.0,2.0},{0.0,0.0,3.0}};
	private static final double[][] QRTestQ = {{0.0,-1.0,0.0},{-1.0,0.0,0.0},{0.0,0.0,1.0}};
	private static final double[][] QRTestR = {{-1.0,-1.0,-2.0},{0.0,-1.0,-1.0},{0.0,0.0,3.0}};

	private static final double[][] ZEROS4x4 = {{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0}};
	private static final double[][] EYE4 = {{1.0,0.0,0.0,0.0},{0.0,1.0,0.0,0.0},{0.0,0.0,1.0,0.0},{0.0,0.0,0.0,1.0}};
	
	private static final double DELTA = 1.0E-4;
	
	//@Test
	public void testQRDecomposition() {

	}

	@Test
	public void testIdentity() {
		double[][] test = MatrixSupport.Identity(4);
		assertMatrixCloseTo(test,EYE4);
	}
	
	@Test
	public void testMatrixofZeros() {
		double[][] test = MatrixSupport.MatrixofZeros(4);
		assertMatrixCloseTo(test,ZEROS4x4);
		
		test = MatrixSupport.MatrixofZeros(4,4);
		assertMatrixCloseTo(test,ZEROS4x4);
	}
	
	private void assertMatrixCloseTo(double[][] expected, double[][] actual) {
		if(actual.length != expected.length)
			fail("actual m ("+Integer.toString(actual.length)+") != expected m ("
					+Integer.toString(expected.length)+")");
		
		for(int i=0;i<actual.length;i++) {
			if(actual[i].length != expected[i].length)
				fail("actual n ("+Integer.toString(actual[i].length)+") != expected n ("
						+Integer.toString(expected[i].length)+") on row "+Integer.toString(i));
			
			for(int j=0;j<actual[i].length;j++) {
				assertCloseTo(expected[i][j],actual[i][j]);
			}
			
		}
	}
	
	private void assertCloseTo(double expected, double actual) {
		assertTrue(expected+DELTA > actual);
		assertTrue(expected-DELTA < actual);
	}
}
