(*  Elemente der Programmierung 2,  WQ FS 2013 *)

(*  Funktionen mit optionalen Parametern *)

potReihe[f_,x_:x,xo_:0,order_:6]:= Series[f,{x,xo,order}]

potReihe[Sin[x],x]

potReihe[Sin[x],x,Pi,3]

(* 'bessere' Programmierung ist aber, Standardwerte als Optionen zu formulieren *)

Clear[potReihe]

Options[potReihe]:={val->x,value->0,order->6};

potReihe[f_,Opts___?OptionQ]:=Series[f,{var,value,order} /. {Opts} /. Options[potReihe] ]

potReihe[Sin[y],var->y,order->7]

(* kleine Programmierbeispiele fuer Berechnung der Zahl Pi *)

ClearAll[archi]

archi[s_,c_,n_]:=Module[{x=c,y=s,t,j=0},
While[j<n,j=j+1;
x=Sqrt[(1+x)/2]; y=y/x;  t=y/x;
Print["n= ",j,"  S= ",  N[y,13],"   < Pi=",N[Pi,13], "  <   T=",N[t,13]]];Return[N[{y,t},13]]]

c=0
s=2
archi[s,c,20]

(* relativer Fehler *)
N[Abs[%7[[1]]-Pi]/Pi]
N[Abs[%7[[2]]-Pi]/Pi]

(* next mit Ansatz von Vieta *)

ClearAll[vv,vieta,vietaPi]

vv[x_]:=Sqrt[2.+x];
vieta[x_,n_]:=Nest[vv,x,n-1];
vieta[x_,1]:=x;
vietaPi[n_]:=2.^(n+1)/Product[vieta[Sqrt[2.],m],{m,1,n}];

(* Arbeit von Nest *)
vieta[x,4]

(* Pi in 10.Naeherung *)
viPi10=vietaPi[10]
N[viPi10-Pi]

(* relativer Fehler *)
N[Abs[viPi10-Pi]/Pi]

(*  Pi mit Leibniz'scher Summenformel *)

leibPi[n_]:= N[4 Sum[(-1)^(m+1)/(2 m-1),{m,1,n}]]

lei200=leibPi[200]

(* relativer Fehler *)
N[Abs[lei200-Pi]/Pi]

(* Versuch je 2 +- Terme zusammenzufassen: Bringt nichts *)

leibPi2[n_]:= N[8  Sum[1/(4  m^2-1),{m,1,n/2}]]

lei2mit200=leibPi[200]

(* relativer Fehler *)
N[Abs[lei200-Pi]/Pi]

(*  Volle symbolische Rechnung *)
leibnizPi = 4 Sum[(-1)^(m+1)/(2 m-1),{m,1,Infinity}]

(*  Zufallsexperiment *)

randomPi[n_]:=Module[{p,i=0,m=0},While[i≤ n, i=i+1; m=m+1-Floor[Random[]^2+Random[]^2]];
Return[p=4. m/n]]

randomPi[10000]

(*  also sehr 'schlecht', in anderen Faellen wird der Zufall aber (verbessert) genutzt *)

(*  Modernere Naeherungsrechnung: BBP- Reihe, 1995 *)

bbp[n_]:= N[  Sum[1/16^m(4/(8 m+1)-2/(8 m+4) -1/(8 m+5 )-1/(8 m+6)),{m,0,n}]]
bbp5=bbp[5]
bbp10=bbp[10]

(* relativer Fehler *)
N[Abs[bbp5-Pi]/Pi]

N[Abs[bbp10-Pi]/Pi]

(* kleines Programmierbeispiel: Euklidischer Algorithmus fuer GGT zweier Zahlen *)

euklid[a0_Integer,b0_Integer]:= Module[{a=a0,b=b0,q,r},
While[b≠0,r=Mod[a,b]; q=(a-r)/b;
Print[a, "=", q, "*", b, "+", r]; {a,b}={b,r}];Print["GGT = ", a]]

euklid[12,7]

euklid[330,44]

GCD[330,44]