//----------------------------------
//----------------------------------
//------- Basismathematik ----------
//----------------------------------
//----------------------------------

function ggT(a,b) { // Euklid-Algorithmus
	if (a*b==0) return 1; // Eine Zahl war Null
	if (a<b) {
		var tmp = b;
		b=a;
		a=tmp;
	}
	do {
		c=a%b; // Modulo-Rechnung
		a=b;
		b=c;
	} while (c!=0) // Solange der Rest ungleich Null ist
	return a;
}

function kgV(a,b) {
	if (a*b==0) return 0;
	return a*b/ggt(a,b);
}

function istZahl(curValue) {
	if (typeof curValue != "string") curValue = String(curValue);
	curValue = curValue.replace(/,/g,".");
	if (isNaN(Number(curValue)) || curValue == "") {
		return false;
	}
	return true;
}

function runden(zahl,stellen){
	// zahl auf die Anzahl stellen runden
	var zahl = Math.round(zahl*Math.pow(10,stellen));
	zahl = zahl/Math.pow(10,stellen);
	return zahl;
}

function shiftComma(my_Nbr, width, symbol) {
	//Verschiebt das Symbol(Komma,Punkt) um width (+ rechts, - links) in my_Nbr
	if (width==0) return String(my_Nbr).replace(/\./g,symbol);
	var l=0;
	var Nbr = String(my_Nbr).replace(/\./g,","); //Punkt durch Komma ersetzen.
	var commaPos = Nbr.indexOf(",");
	var toAdd = "";	
	Nbr = Nbr.replace(/\,/g,""); //Komma loeschen bzw ganz nach rechts schieben
	if (commaPos>-1) width = width-(Nbr.length-commaPos); //Dadurch wird width kleiner
	//Fuehrende Nullen loeschen
	while (Nbr.indexOf("0") == 0) Nbr = Nbr.substring(1,Nbr.length);
	if (width>0) { //schieben nach rechts
		toAdd = "";
		for (l = 0;l<width;l++) toAdd+="0";
		Nbr += toAdd;
	} else {
		width = Math.abs(width);
		if (width!=0) {
			if (width>=Nbr.length) { //Nullen vorschreiben
				toAdd = "";
				for (l = 0;l<width-Nbr.length;l++) toAdd+="0";
				Nbr = "0"+symbol+toAdd+Nbr;
			} else {
				Nbr = Nbr.substring(0,Nbr.length-width)+symbol+Nbr.substring(Nbr.length-width,Nbr.length);
			}
		}
		while (Nbr.lastIndexOf("0") == Nbr.length-1) Nbr = Nbr.substring(0,Nbr.length-1);
		while (Nbr.lastIndexOf(symbol) == Nbr.length-1) Nbr = Nbr.substring(0,Nbr.length-1);
	}
	return Nbr;
}

function rnd(u,o) {
	// Zufallszahl zwischen u und o
	return Math.floor(Math.random()*(o-u+1))+u;;
}

function bogenmass(dGrad) {
	return Math.PI*dGrad/180;
}

function grad(dBogenmass) {
	return dBogenmass*180/Math.PI;
}

//----------------------------------
//----------------------------------

//----------------------------------
//----------------------------------
//------ Lineare Algebra  ----------
//----------------------------------
//----------------------------------
function calc2erDet(a1,a2,b1,b2) {	
	return eval(a1*b2 - a2*b1);
}

function calc3erDet(u,v,ab) {
	//u,v,ab sind Vektoren der Laenge 3
	var a11 = u[0];
	var a21 = u[1];
	var a31 = u[2];

	var a12 = v[0];
	var a22 = v[1];
	var a32 = v[2];
	
	var a13 = ab[0];
	var a23 = ab[1];
	var a33 = ab[2];

	var hauptDiag1_1 = a11*a22*a33;
	var hauptDiag1_2 = a12*a23*a31;
	var hauptDiag1_3 = a13*a21*a32;
	
	var nebenDiag1_1 = a31*a22*a13;
	var nebenDiag1_2 = a32*a23*a11;
	var nebenDiag1_3 = a33*a21*a12;

	
	return hauptDiag1_1+hauptDiag1_2+hauptDiag1_3-nebenDiag1_1-nebenDiag1_2-nebenDiag1_3;
}
//----------------------------------
//----------------------------------

//----------------------------------
//----------------------------------
//--------- Vektoren  --------------
//----------------------------------
//----------------------------------
function linearAbh(u,v) {
	//u,v sind Vektoren der Laenge 3
	var referenzWert = 1;
	if (v[0]!=0) referenzWert = v[0]/u[0];
	else if (v[1]!=0) referenzWert = v[1]/u[1];
	else if (v[2]!=0) referenzWert = v[2]/u[2];
	else if (v[0]!=0 || v[1]!=0 || v[2]!=0) return false;
	else return true;

	if (u[0]*referenzWert == v[0] && u[1]*referenzWert == v[1] && u[2]*referenzWert == v[2]) {
		return true;
	}
	return false;
}

function simplifyVpossible(a_) {
	//Gibt true zurŸck, wenn der Vektor vereinfacht werden kann.
	//Dh, wenn ein Faktor aus allen drei Komponenten rausgezogen werden kann.
	//(4;0;2) -> (2;0;1)
	var curGGT = ggt_special(ggt_special(a_[0],a_[1]),a_[2]);
	if (curGGT==1) return false;
	return true;
}

function simplifyV(a_) {
	//Ein Faktor kann aus allen drei Komponenten rausgezogen werden.
	//(4;0;2) -> (2;0;1)
	var curGGT = ggt_special(ggt_special(a_[0],a_[1]),a_[2]);
	var newA_ = new Array(a_[0]/curGGT,a_[1]/curGGT,a_[2]/curGGT);
	return newA_;
}

function istRechtwinklig(a_,b_) {
	//vektoren a, b (Arrays) stehen rechtwinklig aufeinander
	if (sMult(a_,b_)==0) return true;
	return false;
}

function sMult(a_,b_) {
	//Skalarmultiplikation von zwei Vektoren
	return (a_[0]*b_[0]+a_[1]*b_[1]+a_[2]*b_[2]);
}

function sMultV(t,a_) {
	//Multiplikation eines Vektoren mit der Zahl t
	var res = new Array(t*a_[0],t*a_[1],t*a_[2]);
	return res;
}

function VMultV(a_,b_) { 
	//Kreuzprodukt
	var res = new Array(calc2erDet(a_[1],a_[2],b_[1],b_[2]),calc2erDet(a_[2],a_[0],b_[2],b_[0]),calc2erDet(a_[0],a_[1],b_[0],b_[1]));
	return res;
}

function VMinusV(a_,b_) {
	var res = new Array(a_[0]-b_[0],a_[1]-b_[1],a_[2]-b_[2]);
	return res;
}

function VPlusV(a_,b_) {
	var res = new Array(a_[0]+b_[0],a_[1]+b_[1],a_[2]+b_[2]);
	return res;
}

function VBetrag(a_) {
	return (Math.sqrt(a_[0]*a_[0]+a_[1]*a_[1]+a_[2]*a_[2]));
}


//----------------------------------
//----------------------------------

//----------------------------------
//----------------------------------
//--------- Stochastik  ------------
//----------------------------------
//----------------------------------


function fakul(n){
	n= parseInt(n);
	if (n<1) return "Nur natuerliche Zahlen eingeben."
	var fak;
	fak=1;
	for(i=1; i <= n; i++){
		fak = fak*i;
	}
	return fak;
}

function fak(n) {return fakul(n);}

function n_hoch_k(n,k){
	n = parseInt(n);
	k = parseInt(k);
	if (n<1) return "Nur natuerliche Zahlen n eingeben."
	if (k<1) return "Nur natuerliche Zahlen k eingeben."
	var fak;
	fak=1;
	for(i=n; i > n-k; i--){
		fak = fak*i;
	}
	return fak;
}


function n_ueber_k(n, k) {
	n = parseInt(n);
	k = parseInt(k);
	if (n<1) return "Nur natuerliche Zahlen n eingeben."
	if (k<1) return "Nur natuerliche Zahlen k eingeben."
	if (k>n) return "k muss kleiner n sein."
	var binko, n, k, i;
	if(k > n/2){
		k = n-k;
	}
	if(k == 0){
		return 1;
	}
	else{
		binko = 1;
		for(i=1; i <= k; i++){
			binko=binko*(n-i+1)/i;
		}
	}
	return binko;
}

//Mit BerŸcksichtigen der Reihenfolge und ohne Wiederholungen
function mitR_ohneW(n,k) {
	n = parseInt(n);
	k = parseInt(k);
	if (n<1) return "Nur natuerliche Zahlen n eingeben."
	if (k<1) return "Nur natuerliche Zahlen k eingeben."
	return n_ueber_k(n+k-1,k);
}

function mitR_mitW(n,k) {
	return n_hoch_k(n,k);
}

function ohneR_mitW(n,k) {
	return (fakul(n)/fakul(n-k));
}

function ohneR_ohneW(n,k) {
	return n_ueber_k(n,k);
}

function B(n,p,k) {
  var b=1;
  if(n>0) for(i=1; i<=k; i++) b=b*(n-i+1)/i;
  b=b*Math.pow(p,k)*Math.pow(1-p,n-k);
  return b;
}

function F(n,p,x) {
  	var s=0, k, nx;
  	nx=Math.min(Math.floor(x),n);
  	for (k=0; k<=nx; k++) s=s+B(n,p,k);
  	s=Math.round(s*10000)/10000;
  	return s;
}

