function f_(i,x)
{
	return eval(Fkt[i]);
}

function findVars(t,V,x)
{
	var i=0,k=0;
	for(var j=0;j<t.length;j++)
	{
		t[j]=t[j].replace(/ /g,"").toLowerCase();
		if(t[j]=="")continue;
		v=t[j].split("=");
		for(k=0;k<i;k++)if(V[k]==v[0])break;
		if(k<i)continue;
		if(v.length==1)x[i]=Math.random()*20-10;
		else if(v[1].charAt(0)=="[")
		{
			var b=v[1].substring(1,v[1].length-1).split("...");
			b[0]=Number(b[0].replace(/,/,"."));
			if(b.length==1)b[1]=b[0];else b[1]=Number(b[1].replace(/,/,"."));
			x[i]=Math.random()*(b[1]-b[0])+b[0];
		}
		else x[i]=Number(v[1].replace(/,/,"."));
		V[i++]=v[0];
	}
	return i;
}

var Fkt=new Array();
var trigo=0,Grad_rad=Math.PI/180,Rad_grad=180/Math.PI;

function glsl()
{
	trigo="Grad";
	grad_rad=(trigo==1)?Grad_rad:1;rad_grad=(trigo==1)?Rad_grad:1;
	var v=document.f.v.value.replace(/,/g,".").replace(/\n/g," ").replace(/ +/g," ").replace(/ += +/g,"=").toLowerCase();
//	var i_eff=document.f.i_eff.value;
	var FF, F=(FF=document.f.g.value.replace(/ /g,"")).replace(/,/g,".").split("\n");
	if(FF=="")return;
	if(FF.indexOf("x")>-1)v+=" x";
	if(FF.indexOf("y")>-1)v+=" y";
	if(FF.indexOf("z")>-1)v+=" z";
	var x=new Array(3),i,n,j,k=0,ii,xstart=new Array();
	var Vars=new Array();
 	n=findVars(v.split(" "),Vars,x);
	for(i=0;i<F.length;i++)
	{
		if(F[i]=="")continue;
		var MultErg=new Array(/\dx/,/\d\(/,/\)\(/,/x\(/,/\)x/,/pi\(/,/e_\(/,/\dpi/,/\de_/);
		for(j=0;j<MultErg.length;j++)
		do{ii=F[k].search(MultErg[j]);if(ii==-1)break;F[k]=F[k].substr(0,ii+1)+"*"+F[k].substring(ii+1,F[k].length);}while(true);
		if(trigo==0)F[i]=F[i].replace(/°/g,"*3.141592653589793238/180"); else F[i]=F[i].replace(/°/g,"");
		F[i]=F[i].replace(/pi/g,"3.141592653589793238");
		F[i]=F[i].replace(/ê/g,"2.718281828459045235");
		if(F[i].indexOf("=")>-1)F[i]=F[i].split("=").join("-(")+")";
		for(var oink=0;oink<F[i].length-1;oink++)
		{
			var Oink=F[i].substr(oink,2).toLowerCase();
			if(Oink.search(/\d[a-zäöü]/)>-1){F[i]=F[i].substr(0,oink+1)+"*"+F[i].substring(oink+1,F[i].length);oink++;}
		}
		Fkt[k]=translate(F[i].toUpperCase()).replace(/Math/g,"math");
//		Fkt[k]=translate(F[i].toUpperCase().replace(/E/g,"Ê")).replace(/Math/g,"math").replace(/Ê/g,"E");
		for(j=0;j<n;j++){Fkt[k]=eval("Fkt[k].replace(/"+Vars[j].toUpperCase()+"/g,\"_["+j+"]\");");}
		ii=Fkt[k].search(/[A-ZÄÖÜß]/);
		if(ii>-1){v+=" "+Fkt[k].charAt(ii);n=findVars(v.split(" "),Vars,x);i--;continue;}
		
		Fkt[k]=Fkt[k].toLowerCase().replace(/math/g,"Math").replace(/_/g,"x");
		FF+=Fkt[k]+"\n";

		var MultErg=new Array(/\dx/,/\d\(/,/\)\(/,/x\(/,/pi\(/,/e_\(/,/\dpi/,/\de_/);
		for(j=0;j<MultErg.length;j++)
		do{ii=Fkt[k].search(MultErg[j]);if(ii==-1)break;Fkt[k]=Fkt[k].substr(0,ii+1)+"*"+Fkt[k].substring(ii+1,Fkt[k].length);}while(true);
		 k++;
	}
	//alert(Fkt.join("\n")+"\n\n"+Vars);
	var kk=k;
	if(n>k){for(i=k;i<n;i++)Fkt[i]="0";k=n;}
	//if(n!=k){alert("Die Anzahlen der Gleichungen und der Variablen müssen übereinstimmen!");return;}
	var t="";
	var tt="",ttt="";
	niter=document.f.niter[document.f.niter.selectedIndex].text;
	if(niter=="")niter=(n<5)?20:10; else niter=Number(niter);
	var nrepeat=document.f.nrepeat[document.f.nrepeat.selectedIndex].text;
	var i_eff=document.f.i_eff.value;
	for(var ir=0;ir<nrepeat;ir++)
	{
		for(i=0;i<n;i++)xstart[i]=x[i];
		t="";tt="",nniter=0;
		var grund="";
		document.f.t.value=(ir+1)+". Durchlauf";
		if((nniter=solveGS(x,n,niter))<0)
			tt+=(grund="Der Algorithmus konvergiert für diese Startwerte nicht.");
		else
		{
			for(i=0;i<n;i++)
			{
			t+=RR(x[i])+"                          ";
//}
			  if(isNaN(x[i]))tt="Keine Lösung gefunden!\n"+(grund="Ungültiges Funktionsargument während der "+nniter+". Iteration\nim "+(ir+1)+". Durchlauf aufgetreten")+"\n\n";}
			t+="";
			for(i=0;i<kk;i++){var p;t+="f"+(i+1)+"("+Vars.join(",")+") = "+(p=f_(i,x))+"\n";
			  if((tt=="")&&(Math.abs(p)>.1e-4))tt=(ir+1)+". Durchlauf: "+(grund="Nach "+niter+" Iterationen keine Lösung gefunden")+"\n              (siehe Probe)\n\n";}
			t+="";
			for(i=0;i<n;i++)t+=Vars[i]+"0 = "+xstart[i]+"\n";
			t=t.replace(/\./g,",").replace(/ ,/g," 0,").replace(/-,/g,"-0,");
			  if(tt==""){tt="Lösung im "+(ir+1)+". Durchlauf nach "+nniter+" Iterationen gefunden:\n\n";
			break;}
			if(ir<nrepeat-1)
			{
				ttt+=(ir+1)+". Durchlauf\n  Startwerte:\n";
				for(i=0;i<n;i++)ttt+="    "+Vars[i]+"0 = "+xstart[i]+"\n";
				ttt+="  "+grund+"\n\n";
			}
		}
		findVars(v.split(" "),Vars,x);
		for(i=0;i<n;i++)if(x[i]!=xstart[i])break;
		if(i==n)break;
	}
	ttt=ttt.replace(/\./g,",").replace(/ ,/g," 0,").replace(/-,/g,"-0,").replace(/, /g,". ");
		document.f.t.value=t+"";
		if (document.f.t.value.indexOf("neu") != -1)
	    glsl();
}

function RR(x)
{
	var ieff=Math.round(x*1e12)/1e12;
	var i_eff=Math.round(((Math.pow(ieff,12)-1)*100)*100)/100;
	  if (ieff > 0 && ieff < 2)
	{return(i_eff);}
  else return("neu");
}

function solveGS(x,n,schritte)
{
	var i,j,k,c=new Array(n*n), ff=new Array(n*n),s,ss=1e+300,d,ds,xx=new Array(n);
	for(i=0;i<schritte;i++)
	{
		for(j=0;j<n;j++)xx[j]=x[j];
		s=MakeFVektor(ff,x,n);
		if(s-ss>10)return -i-1;ss=s;
		JacobiMatrix(c,x,ff,n);//alert(c);
		MatrixInvert(c,n);
		//InverseMatrix(c,n);//alert(c);
		for(j=0;j<n;j++)
		{
			for(k=0;k<n;k++){x[j]-=(d=c[j*n+k]*ff[k]);ds+=Math.abs(d)}
			if(isNaN(x[j]))return i+1;
		}
		for(k=0;k<n;k++){if(Math.abs(xx[k]-x[k])>1e-14)break;}
		if(k==n)return i;
		if(ds<1e-15)return i+1;
	}
	return schritte;
}

function MakeFVektor(m,x,n)
{
	var i,s=0;
	for(i=0;i<n;i++){m[i]=f_(i,x);s+=Math.abs(m[i]);}
	return s;
}

function InverseMatrix(M_,n)
{
	var nn,a,b,c,d,e,f,g,h,i,j,k;
	a=M_[0];b=M_[1];c=M_[2];d=M_[3];
	if(n==2)
	{
		nn=a*d-b*c;
		M_[0]=d/nn;M_[1]=-b/nn;M_[2]=-c/nn;M_[3]=a/nn;
	}
	else if(n==3)
	{
		e=M_[4];f=M_[5];g=M_[6];h=M_[7];i=M_[8];
		nn=a*(e*i-f*h)+b*(f*g-d*i)+c*(d*h-e*g);
		M_[0]=(e*i-f*h)/nn;
		M_[1]=(c*h-b*i)/nn;
		M_[2]=(b*f-c*e)/nn;
		M_[3]=(f*g-d*i)/nn;
		M_[4]=(a*i-c*g)/nn;
		M_[5]=(c*d-a*f)/nn;
		M_[6]=(d*h-e*g)/nn;
		M_[7]=(b*g-a*h)/nn;
		M_[8]=(a*e-b*d)/nn;
	}
	else if(n==4)
	{
		var mm0=M_[0],mm1=M_[1],mm2=M_[2],mm3=M_[3],mm4=M_[4];
		var mm5=M_[5],mm6=M_[6],mm7=M_[7],mm8=M_[8],mm9=M_[9],mm10=M_[10],mm11=M_[11];
		var mm12=M_[12],mm13=M_[13],mm14=M_[14],mm15=M_[15];
		nn=mm15*(mm10*(mm0*mm5-mm1*mm4)+mm9*(mm2*mm4-mm0*mm6)+mm8*(mm1*mm6-mm2*mm5));
		nn-=mm14*(mm11*(mm0*mm5-mm1*mm4)+mm9*(mm3*mm4-mm0*mm7)+mm8*(mm1*mm7-mm3*mm5));
		nn+=mm13*(mm11*(mm0*mm6-mm2*mm4)+mm10*(mm3*mm4-mm0*mm7)+mm8*(mm2*mm7-mm3*mm6));
		nn-=mm12*(mm11*(mm1*mm6-mm2*mm5)+mm10*(mm3*mm5-mm1*mm7)+mm9*(mm2*mm7-mm3*mm6));
		M_[0]=(mm15*(mm5*mm10-mm6*mm9)+mm14*(mm7*mm9-mm5*mm11)+mm13*(mm6*mm11-mm7*mm10))/nn;
		M_[1]=-(mm15*(mm1*mm10-mm2*mm9)+mm14*(mm3*mm9-mm1*mm11)+mm13*(mm2*mm11-mm3*mm10))/nn;
		M_[2]=(mm15*(mm1*mm6-mm2*mm5)+mm14*(mm3*mm5-mm1*mm7)+mm13*(mm2*mm7-mm3*mm6))/nn;
		M_[3]=-(mm11*(mm1*mm6-mm2*mm5)+mm10*(mm3*mm5-mm1*mm7)+mm9*(mm2*mm7-mm3*mm6))/nn;
		M_[4]=-(mm15*(mm4*mm10-mm6*mm8)+mm14*(mm7*mm8-mm4*mm11)+mm12*(mm6*mm11-mm7*mm10))/nn;
		M_[5]=(mm15*(mm0*mm10-mm2*mm8)+mm14*(mm3*mm8-mm0*mm11)+mm12*(mm2*mm11-mm3*mm10))/nn;
		M_[6]=-(mm15*(mm0*mm6-mm2*mm4)+mm14*(mm3*mm4-mm0*mm7)+mm12*(mm2*mm7-mm3*mm6))/nn;
		M_[7]=(mm11*(mm0*mm6-mm2*mm4)+mm10*(mm3*mm4-mm0*mm7)+mm8*(mm2*mm7-mm3*mm6))/nn;
		M_[8]=(mm15*(mm4*mm9-mm5*mm8)+mm13*(mm7*mm8-mm4*mm11)+mm12*(mm5*mm11-mm7*mm9))/nn;
		M_[9]=-(mm15*(mm0*mm9-mm1*mm8)+mm13*(mm3*mm8-mm0*mm11)+mm12*(mm1*mm11-mm3*mm9))/nn;
		M_[10]=(mm15*(mm0*mm5-mm1*mm4)+mm13*(mm3*mm4-mm0*mm7)+mm12*(mm1*mm7-mm3*mm5))/nn;
		M_[11]=-(mm11*(mm0*mm5-mm1*mm4)+mm9*(mm3*mm4-mm0*mm7)+mm8*(mm1*mm7-mm3*mm5))/nn;
		M_[12]=-(mm14*(mm4*mm9-mm5*mm8)+mm13*(mm6*mm8-mm4*mm10)+mm12*(mm5*mm10-mm6*mm9))/nn;
		M_[13]=(mm14*(mm0*mm9-mm1*mm8)+mm13*(mm2*mm8-mm0*mm10)+mm12*(mm1*mm10-mm2*mm9))/nn;
		M_[14]=-(mm14*(mm0*mm5-mm1*mm4)+mm13*(mm2*mm4-mm0*mm6)+mm12*(mm1*mm6-mm2*mm5))/nn;
		M_[15]=(mm10*(mm0*mm5-mm1*mm4)+mm9*(mm2*mm4-mm0*mm6)+mm8*(mm1*mm6-mm2*mm5))/nn;
	}
	else
	{
		a=0;
		var nn=n*n,nn1=nn+1;nnn=nn1*nn;
		M=new Array(nnn),v=new Array(nn);//alert(m.join("  "));
		for(i=0;i<nnn;i++)M[i]=0;
		for(i=0;i<n;i++)M[nn+i*(n+1)*nn1]=1;//alert(M.join("   "));
		for(i=0;i<n;i++)
		{
			for(j=0;j<n;j++)
			{
				for(k=0;k<n;k++)
				{
					M[k*n+j+nn1*(i*n+j)]=M_[i*n+k];
//alert(i+"  "+j+"  "+k+"\nM["+(k*n+j+nn1*(i*n+j))+"]   M_["+(i*(n+1)+k)+"]\n"+M.join("   "));
				}
			}
		}
		//alert(M.join("  "));
		GLSL(M,M_,nn);
		//alert(M.join("  "));
	}
}

function JacobiMatrix(m,x,fff,n)
{
	var i,j,xx,ff,d=0.0000000001;
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
		{
			xx=x[j];
			x[j]=xx+d;
			ff=f_(i,x);
			x[j]=xx;
			m[i*n+j]=(ff-fff[i])/d;
		}
}

function translate(t)
{
	var MultErg=new Array(/\d[a-z]/,/\d\(/,/\)\(/,/x\(/,/\)x/,/pi\(/,/e_\(/,/\dpi/,/\de_/,/\)[a-z]/);
	for(j=0;j<MultErg.length;j++)
		do{i=t.search(MultErg[j]);if(i==-1)break;t=t.substr(0,i+1)+"*"+t.substring(i+1,t.length);}while(true);
t="("+t+")";
var n=0,d;
var j=0,k=0,i=0;
t=t.replace(/'/g,"^");
if(t.indexOf("^")>-1)
for(i=0;i<t.length;i++)
if (t.substr(i,1)=="^")
{j=parsefind(t,i,-1); k=parsefind(t,i,1);
t=t.substring(0,j+1)
+ "Math.pow(" 
+ t.substring(j+1,i)
+ ","+t.substring(i+1,k)+")"
+ t.substring(k,t.length);
n++;if(n>15)break;
}n=0;
if(t.indexOf("!")>-1)
for(i=0;i<t.length;i++)
if (t.substr(i,1)=="!")
{j=parsefind(t,i,-1);
t=t.substring(0,j+1) + "fak(" + t.substring(j+1,i)+")"+ t.substring(i+1,t.length);
n++;if(n>15)break;}
	if(t=="") return "(0)";
	if(t==null) return;
	var tt=t;
	t=t.replace(/solve/g,"solvä");
	t=t.replace(/eile/g,"äilä");
	t=t.replace(/legendre/g,"lägändrä");
	t=t.replace(/factor_vec/g,"factor_väc");
	t=t.replace(/newton/g,"näwton");
	t=t.replace(/fresnelc/gi,"fräsnälc");
	t=t.replace(/fresnels/gi,"fräsnäls");
	t=t.replace(/\n/g,"").replace(/\r/g,"");
//	t=t.replace(/\+/g,"+");
	t=t.replace(/\-/g,"-");
	t=t.replace(/\—/g,"-");
	t=t.replace(/\–/g,"-");
	t=t.replace(/\·/g,"*");
	t=t.replace(/\*/g,"*");
	t=t.replace(/\//g,"/");
	t=t.replace(/modpow/gi,"m@dp@w");
	t=t.replace(/modmult/gi,"m@dmult");
	t=t.replace(/mod/gi,"%");
	t=t.replace(/ \^ /g,"^");
	t=t.replace(/Math\./g,"").replace(/sqrt/g,"sqr");
	t=t.replace(/pow/gi,"Math.pow");
	t=t.replace(/m\@dp\@w/g,"modpow");
	t=t.replace(/m\@dmult/g,"modmult");
	//if (trigo==0)
	{
	t=t.replace(/atanh/gi,"at~anh");
	t=t.replace(/asinh/gi,"as~inh");
	t=t.replace(/acosh/gi,"ac~osh");
	t=t.replace(/sinh/gi,"sinh");
	t=t.replace(/cosh/gi,"cosh");
	t=t.replace(/tanh/gi,"tanh");
	t=t.replace(/coth/gi,"coth");
	t=t.replace(/acoth/gi,"cot");
	t=t.replace(/atan/gi,"at~an");
	t=t.replace(/asin/gi,"as~in");
	t=t.replace(/acos/gi,"ac~os");
	t=t.replace(/acot/gi,"cot");
	t=t.replace(/sin/gi,"sin");
	t=t.replace(/cos/gi,"cos");
	t=t.replace(/tan/gi,"tan");
	t=t.replace(/cot/gi,"cot");
	t=t.replace(/ascsh/gi,"ascsh");
	t=t.replace(/ascs/gi,"ascs");
	t=t.replace(/scsh/gi,"scsh");
	t=t.replace(/scs/gi,"scs");
	t=t.replace(/°/g,"*(pi)/180");
      }if(trigo==1)t=t.replace(/°/g,"");
	t=t.replace(/sqrt/gi,"sqr");
	t=t.replace(/sqr/gi,"Math.sqrt");
	t=t.replace(/abs/gi,"Math.abs");
	t=t.replace(/int/gi,"Math.floor");
	t=t.replace(/log\(/gi,"Math.log(");
	t=t.replace(/ln/gi,"Math.log");
	t=t.replace(/geoM/gi,"gäoM");
	t=t.replace(/asech/gi,"asäch");
	t=t.replace(/sech/gi,"säch");
	t=t.replace(/asec/gi,"asäc");
	t=t.replace(/sec/gi,"säc");
	t=t.replace(/exp/gi,"Math.ä@p");
	t=t.replace(/cent/gi,"cänt");
	t=t.replace(/sv\(/gi,"sv(");
	t=t.replace(/kgv/gi,"kgV");
	t=t.replace(/ggt/gi,"ggT");
	t=t.replace(/x/g,"X").replace(/y/g,"Y");
	t=t.replace(/pi/gi,"Math.PI");
	t=t.replace(/\de/gi,"ä");
	t=t.replace(/e/gi,"(Math.E)");
	t=t.replace(/ä/g,"e").replace(/@/g,"x");
	t=t.replace(/\~/g,"");
	t=t.replace(/\|/g,","); //alert(t);
	if(t.indexOf("solve(")>-1)
	{
		i=0;var ii=0,iii,ts=t;
		do{
			iii=ts.indexOf("solve(");
			if(iii==-1)break;
			ii=parsefind(ts,iii,1);
			t=t.substr(0,iii+i+6)+"'"+t.substring(iii+i+6,ii+i-1)+"'"+t.substring(ii+i-1,t.length);
			i+=iii+1;
			ts=ts.substring(ii+1,ts.length);
		}while(true);
	}
	while(t.search(/p\d/)>-1)
			{i=t.search(/p\d/);j0=parsefind(t,i,-1);
			j1=parsefind(t,i,1);d=DezToBruch(t.substring(j0+1,j1));
			t=t.substr(0,j0+1)+"("+d+")"+t.substring(j1,t.length);}
if (t=="") t="0";
//alert(t);
return t.substr(1,t.length-2);
}

function parsefind(t,i,r)
{
var L_=t.length, k=0, j=0;
for(j=i+r;(j<L_)&&(j>=0);j+=r)
{
var u=t.substr(j,1);
if(u=="(")k++; else if(u==")")k--;
if(k*r<0)return j;
if((k==0)&&((u=="+")||(u=="-")||(u=="*")||(u=="/")||(u==";")||(u==",")||(u=="=")||(u=="\"")||(u=="'")||(u=="|")||(j+r==L_+1)||(j+r==-1))) return j;
}
return j;
}

