package dmrgvisu2;

public class Op
{
	private static final long serialVersionUID = 1L;
	int N;
	Matrix[] A;
	int states;
	int local[];
	public Op(int N)
	{
		this.local = new int[0];
		this.N=N;									// Laenge der Kette
		this.states=2;								// Anzahl der moeglichen Zustaende (Anzahl der Matrizen pro Kettenplatz)
		this.A = new Matrix[this.N];
		for (int i=0; i<this.N; i++)
			this.A[i]=new Matrix(this.states, this.states);
		this.FillA1();
	}
	public void SetLocalOp(int local, Matrix LocalOp)
	{
		this.DelLocalOp(local);
		int[] newLocal = new int[this.local.length+1];
		for (int i=0; i<this.local.length;  i++)
			newLocal[i] = this.local[i];
		newLocal[this.local.length] = local;
		this.local = newLocal;
		this.A[local] = LocalOp;
	}
	public void DelLocalOp(int local)
	{
		if (this.local.length == 0)
			return;
		int Found = 0;
		int [] newLocal = new int[this.local.length-1];
		for (int i=0; i<newLocal.length; i++)
		{
			if (this.local[i]==local)
			{
				this.A[this.local[i]] = new Matrix(this.states, this.states);
				for (int j=0; j<this.states; j++)
					this.A[this.local[i]].SetContent(j,j,1);		
				Found++;
			}
			else
				newLocal[i] = this.local[i+Found];
		}
		this.local = newLocal;
	}
	public void FillA1()
	{
		for (int i=0; i<this.N; i++)
			for (int j=0; j<this.states; j++)
				this.A[i].SetContent(j,j,1);
	}
	public String toString()
	{
		String newString = "";
		for (int i=0; i<this.N; i++)
		{
			newString = newString + this.A[i];
		}
		return newString;
	}
	public double ScalarProd(Mps a, Mps b)
	{
		double out=0.0;
		a.A[this.local[0]][0].printreadable();
		a.A[this.local[0]][1].printreadable();
		b.A[this.local[0]][0].printreadable();
		b.A[this.local[0]][1].printreadable();
		
		if (this.local.length == 1 && a==b && false)
		{
//			System.out.println("Summe über Spur (" + this.states + ")");
			for (int j=0; j<this.states; j++)
			{
				for (int k=0; k<this.states; k++)
				{
					out += this.A[this.local[0]].GetContent(j,k) * (a.A[this.local[0]][j].trans().mult(b.A[this.local[0]][k])).Trace();
					System.out.println(this.A[this.local[0]].GetContent(j,k) + " *");
					(a.A[this.local[0]][j].trans().mult(b.A[this.local[0]][k])).printreadable();
				}
			}
		}
		else
		{
			System.out.println("Summe über Produkte");
			Matrix temp = new Matrix();
			Matrix temp2 = new Matrix(a.A[0][0].GetSize()[0], b.A[0][0].GetSize()[0]);
			for (int i=0; i<temp2.GetSize()[1] && i<temp2.GetSize()[0];i++)
				temp2.SetContent(i,i,1);

			for (int i=0; i<this.N; i++)
			{
				temp = new Matrix(a.A[i][0].GetSize()[1], b.A[i][0].GetSize()[1]);
				for (int j=0; j<this.states; j++)
				{
					for (int k=0; k<this.states; k++)
					{
						temp = new Matrix(temp.add((a.A[i][j].trans().mult(temp2.mult(b.A[i][k]))).mult(this.A[i].GetContent(j,k))));
					}
					
				}
				temp2 = new Matrix(temp);
			}
			out = temp.GetContent(0,0);
		}
		return out;
	}
}
