// z: Zähler, n: Nenner
// lz,ln: Lösungen
// nz: Anzahl Zeilen
function matrixinvb(z,n,nz)
{
	var i, j, k, d,nn=nz*nz, zi=new Array(nn),ni=new Array(nn),i0,i1;
	for(i=0;i<nn;i++){ni[i]=1;zi[i]=0;}
	for(i=0;i<nn;i+=nz+1)zi[i]=1;
	var qz,qn,abbruch=(1==0);
	
	
	for (j = 0;j<nz;j++)
	{
		status="Gaußscher Algorithmus mit Brüchen - "+Math.round(j*100/nz)+"% fertig";
		// Diagonalenfeld normalisieren
		d=j*nz+j; // Index Diagonalenfeld
		if (z[d]==0)
		{
			//Gewährleisten, daß keine 0 in der Diagonale steht
			for(i=j+1;i<nz;i++)
			{
				// Suche Reihe mit Feld <> 0 und tausche
				if (z[i*nz+j]!=0)
				{
					var fi=i*nz+j;
					for(k=0;k<nz;k++)
					{
						var X=n[i0=j*nz+k];n[i0]=n[i1=i*nz+k];n[i1]=X;X=z[i0];z[i0]=z[i1];z[i1]=X;
						X=ni[i0];ni[i0]=ni[i1];ni[i1]=X;X=zi[i0];zi[i0]=zi[i1];zi[i1]=X;
					}
                    		break;
                		}
            	}
		}
		if((z[d]!=0)&&(z[d]!=n[d]))
		{
            	// Diagonalen auf 1 bringen
			for(k=0;k<nz;k++)
					geteilt2(zi,ni,j*nz+k,z[d],n[d],j*nz+k,true);
		
			for(k=0;k<nz;k++)
				if(k!=j)
				{
					geteilt(z,n,j*nz+k,d,j*nz+k,true);
				}
				z[d]=1;n[d]=1;
			//	zi[d]=1;ni[d]=1;
		}

		// Spalten außerhalb der Diagonalen auf 0 bringen
		//for(i=0;i<nn);i++){kuerzen(z,n,i);kuerzen(zi,ni,i);

		for (i = 0 ; i< nz ; i++)
		{
			if (i != j )
			{
				var qz=z[i*nz+j],qn=n[i*nz+j];
				if(qz!=0)
				{
					for(k=0;k<nz;k++)minus(z,n,i*nz+k,j*nz+k,i*nz+k,1,1,qz,qn,true);
					for(k=0;k<nz;k++)minus(zi,ni,i*nz+k,j*nz+k,i*nz+k,1,1,qz,qn,true);
					//alert("Zeile "+j+"\nZähler: "+ z.join("   ")+"\nNenner: "+n.join("   "));
				}
				for(k=0;k<nz;k++)if(z[i*nz+k]!=0)break;
				if(k==nz)
				{
					abbruch=true;
					break;
				}
			}
		}
		if(abbruch)break;
		//alert(toStr(zi,ni,nz));
	}
	
	for(i=0;i<nz;i++)for(j=0;j<nz;j++)if(z[i*nz+j]!=((i==j)?1:0))return false;

	for(i=0;i<nn;i++)
	{
		n[i]=ni[i];z[i]=zi[i];
	}
	return true;
}
function plus2(z,n,i,zj,nj,k,fiz,fin,fjz,fjn,kuerzn)
{
	var nn=n[i]*nj*fin*fjn,zz=fiz*z[i]*nj*fjn+fjz*zj*n[i]*fin;
	z[k]=zz;n[k]=nn;
	if(kuerzn)kuerzen(z,n,k);
}	
function minus2(z,n,i,zj,nj,k,fiz,fin,fjz,fjn,kuerzn)
{
	return plus(z,n,i,zj,nj,k,fiz,fin,-fjz,fjn,kuerzn);
}
function mal2(z,n,i,zj,nj,k,fz,fn,kuerzn)
{
	n[k]=n[i]*nj*fn;z[k]=f*z[i]*zj;
	if(kuerzn)kuerzen(z,n,k);
}	

function geteilt2(z,n,i,zj,nj,k,kuerzn)
{
//	alert("vor geteilt"+i+":"+j+"->"+k+"\nZähler: "+ z.join("   ")+"\nNenner: "+n.join("   ")+"\n");
	var nn=n[i]*zj;
	z[k]=z[i]*nj;
	n[k]=nn;
//	alert("nach geteilt\nZähler: "+ z.join("   ")+"\nNenner: "+n.join("   ")+"\n");
	if(kuerzn)kuerzen(z,n,k);
}	

function toStrDez(m,nz,r)
{
	if(r==null)r=100000000;
	var nn=nz*nz,k=new Array(nn),i,maxlen0=new Array(nz),maxlen1=new Array(),t="";
	for(i=0;i<nz;i++)maxlen0[i]=maxlen1[i]=0;
	for(i=0;i<nn;i++)
	{
		m[i]=Math.round(m[i]*r)/r;
		k[i]=String(m[i]).indexOf(".");
		if(k[i]==-1)k[i]=String(m[i]).length;
		maxlen0[i%nz]=Math.max(maxlen0[i%nz],k[i]);
		maxlen1[i%nz]=Math.max(maxlen1[i%nz],String(m[i]).length-k[i]);
	}
	for(i=0;i<nn;i++)
	{
		t+="                   ".substr(0,maxlen0[i%nz]-k[i]+2)+m[i];
		t+="                   ".substr(0,maxlen1[i%nz]-String(m[i]).length+k[i]);
		if((i%nz)==nz-1)t+=" \n\n";
	}
	return t.replace(/\./g,",").replace(/ -,/g,"-0,").replace(/ ,/g,"0,");
}

