package math.matrix;

import exception.IllegalDimensionException;
import math.Sequence;

/**
 * Symmetric matrix object d<sub>ij</sub>=d<sub>ji</sub>&isin;&#x211D;
 * with n rows and n columns
 * @author Daniel Weschke
 */
public class Symmetric extends Matrix {

	/**
	 * UID
	 */
	private static final long serialVersionUID = -3506578822884073555L;
	
	public Symmetric(int n){
		this.m = n;
		this.n = n;
		data = new double[Sequence.triangularNumber(n)];
	}
	
	public Symmetric(double... d){
		this((int)Math.ceil(Sequence.triangularRoot(d.length)));
		int i;
        for(i=0; i<d.length; i++)
        	set(i, d[i]);
	}
	
	public Matrix set(int i, double d){
		data[i] = d;
		return this;
	}
	
	public Matrix set(int i, int j, double d){
		data[index(i,j)] = d;
		return this;
	}
	
	public double get(int i, int j){
		return get(index(i,j));
	}
	
	private int index(int i, int j){
		return i>j?Sequence.triangularNumber(i)+j:i+Sequence.triangularNumber(j);
	}

    /**
     * Adds two matrices of the same dimension (entrywise addition).
     * The addition of two n-by-n matrices <b>A</b> and <b>B</b>,
     * is again an n-by-n matrix computed by adding corresponding elements.
     * @param B matrix
     * @return <b>C</b> = <b>A</b> + <b>B</b>, entrywise summarized matrix
     * @throws IllegalDimensionException
     */
    public Matrix plus(Matrix B) throws IllegalDimensionException{
    	checkDimensions(B);
    	int i,j;
        Matrix c = createAddition(B);
        c.newOperation();
        if(B instanceof Diagonal)
        	for(i=0; i<m; i++)
        		for(j=i; j<n; j++){
        			c.set(i, j, get(i,j)+((Diagonal) B).get(i));
        			c.operate();
        		}
        else if(B instanceof Symmetric)
        	for(i=0; i<m; i++)
        		for(j=i; j<n; j++){
        			c.set(i,j, get(i,j)+B.get(i,j));
        			c.operate();
        		}
        else
        	for(i=0; i<m; i++)
        		for(j=0; j<n; j++){
        			c.set(i,j, get(i,j)+B.get(i,j));
        			c.operate();
        		}
//        System.out.println(this instanceof Symmetric);
//        System.out.println(B instanceof Symmetric);
        return c;
    }
	
    public static void main(String[] args){
		Symmetric s1 = new Symmetric(1.);
		System.out.println(s1);
		Symmetric s2 = new Symmetric(1., 2.);
		System.out.println(s2);
		Symmetric s3 = new Symmetric(1., 2., 3.);
		System.out.println(s3);
		Symmetric s4 = new Symmetric(1., 2., 3., 4.);
		System.out.println(s4);
		System.out.println(s4.get(0,2));
		System.out.println(s4.get(2,0));
		try {
			System.out.println(s2.plus(s3));
			System.out.println("Operations: "+s2.plus(s3).getOperationsTotal());
			System.out.println(s2.minus(s3));
		} catch (IllegalDimensionException e) {
			e.printStackTrace();
		}
	}
}
